Object Mapper

Descripcion

Como utilizar la clase ObjectMapper para convertir objetos con distintos atributos (mapear un objeto dentro de otro)

Dependencia pom.xml

Para utilizar el ObjectMapper tenemos que incluir la siguiente dependencia en el pom.xml:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>
Metodo

El ObjectMapper de la libreria jackson nos permite mapear objetos de distintas maneras, entre otras nos permite mapear objectos json a un objeto de java por ejemplo, o tambien mapear dos objetos que son similares pero no iguales (mapear solo los atributos que compartan).

En este ejemplo tenemos dos objetos:

cocheTipoA con los siguientes atributos:

    private int puertas;
    private int ruedas;
    private int tipoA;
  

y cocheTipoB con los siguientes atributos:

    private int puertas;
    private int ruedas;
  

Como podemos ver los dos objetos comparten dos atributos puertas y ruedas, asi que podemos usar un codigo como el siguiente para meter un objeto cocheTipoB dentro de un objeto cocheTipoA:

           package com.mycompany.app;

import com.fasterxml.jackson.databind.ObjectMapper;


public class App
{

    public static void main( String[] args )
    {

        cocheTipoA cocheA;

        cocheTipoB cocheB = new cocheTipoB();

        ObjectMapper mapper = new ObjectMapper();

        cocheB.setPuertas(5);

        cocheA = mapper.convertValue(cocheB, cocheTipoA.class);

        System.out.println( cocheA.getPuertas() );
    }
}

NOTA: para utilizar el ObjectMapper tenemos que hacer el siguiente imrpot: import com.fasterxml.jackson.databind.ObjectMapper;

En este caso creamos un objeto cocheTipoB le asignamos un valor de 5 al numero de puertas y despues mapeamos el objeto cocheTipoB a un objeto cocheTipoA y a continuacion imprimimos el resultado del objeto cocheTipoA dando el resultado que habiamos asignado al objeto cocheTipoB por lo tanto el mapeo ha funcionado correctamente

Sin embargo si hacemos el mapeo al reves y mapeamos el objeto cocheTipoA dentro de un objeto cocheTipoB ocurre lo siguiente:

           package com.mycompany.app;

import com.fasterxml.jackson.databind.ObjectMapper;

public class App
{

    public static void main( String[] args )
    {

        cocheTipoA cocheA = new cocheTipoA();

        cocheTipoB cocheB;

        ObjectMapper mapper = new ObjectMapper();

        cocheA.setPuertas(5);

        cocheB = mapper.convertValue(cocheA, cocheTipoB.class);

        System.out.println( cocheB.getPuertas() );
    }
}
Exception in thread "main" java.lang.IllegalArgumentException: Unrecognized field "tipoA" (class com.mycompany.app.cocheTipoB), not marked as ignorable (2 known properties: "puertas", "ruedas"])

En este caso estamos intentando mapear un objeto que tiene un atributo tipoA dentro de un objeto que no lo tiene, a pesar de que los otros atributos si que los tiene, y el error que se lanza precisamente es que el atributo tipoA no esta dentro del objeto cocheTipoB, para resolver este problema y hacer que el ObjectMapper ignore ese atributo y mapee solo los atributos que si que coinciden podemos configurar el ObjectMapper de la siguiente manera:

Usame el metodo configure del mapper

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

El codigo final quedaría tal que así:

package com.mycompany.app;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;

public class App
{

    public static void main( String[] args )
    {

        cocheTipoA cocheA = new cocheTipoA();

        cocheTipoB cocheB;

        ObjectMapper mapper = new ObjectMapper();

        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        cocheA.setPuertas(5);

        cocheB = mapper.convertValue(cocheA, cocheTipoB.class);

        System.out.println( cocheB.getPuertas() );
    }
}
Tags

ObjectMapper | Jackson | java